home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / displytl / displytl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  42.5 KB  |  1,530 lines

  1. /*
  2.  * Copyright (c) 1990, 1991, 1992 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23. /* $Header: /Source/Media/collab/DisplayTool/RCS/DisplayTool.c,v 1.42 93/02/07 17:48:10 drapeau Exp $ */
  24. /* $Log:    DisplayTool.c,v $
  25.  * Revision 1.42  93/02/07  17:48:10  drapeau
  26.  * Mostly cosmetic changes, adding calls to the new function "UpdateHeader()"
  27.  * to indicate the state of the currently opened document.
  28.  * 
  29.  * Revision 1.41  92/10/30  19:09:38  drapeau
  30.  * Minor modifications to remove extraneous diagnostic messages.
  31.  * 
  32.  * Revision 1.4  92/10/30  18:48:43  drapeau
  33.  * Slight modifications to improve reporting of diagnostics, and in the
  34.  * NullFields() function to initialize a new ImageStruct.
  35.  * 
  36.  * Revision 1.3  92/10/29  17:53:37  drapeau
  37.  * Minor adjustments to functions responsible for creating and painting the
  38.  * popup canvases used when displaying an image full-size.  The problem occurred
  39.  * when a slide contained multiple images to be drawn: the result was that the
  40.  * same image would be drawn in each of the full-sized canvases, instead of each
  41.  * separate image being drawn in the separate canvases.
  42.  * 
  43.  * Revision 1.2  92/10/29  13:51:47  drapeau
  44.  * Re-designed major parts of the application.  Cleaned up the interface to
  45.  * the underlying image creation code.  Improved memory usage.  Improved
  46.  * performance.  Improved robustness and error recovery.  Too many other
  47.  * changes to mention here.  This is the first public release of the code.
  48.  * 
  49.  * Revision 1.1  92/09/29  01:04:00  drapeau
  50.  * Initial revision
  51.  * 
  52.  * Revision 1.2  92/04/17  00:55:32  bryant
  53.  * Integrated the xv-211 code
  54.  * 
  55.  * Revision 1.1  92/04/01  21:26:30  bryant
  56.  * Initial revision
  57.  *  */
  58. static char rcsid[] = "$Header: /Source/Media/collab/DisplayTool/RCS/DisplayTool.c,v 1.42 93/02/07 17:48:10 drapeau Exp $";
  59.  
  60. #include "DisplayTool.h"
  61. #include "externs.h"
  62.  
  63. int main(int argc, char *argv[])
  64. {
  65.   int  i;
  66.   FILE *fp;
  67.   char *firstLine = "#DisplayTool Document#";
  68.   char header[30];
  69.   
  70.   static DispatchTable  DT = 
  71.     {
  72.       OpenDoc,
  73.       GetDoc,
  74.       GetSelection,
  75.       SetSelection,
  76.       PerformSelection,
  77.       NULL,
  78.       NULL,
  79.       NULL,
  80.       NULL,
  81.       NULL,
  82.       NULL,
  83.       HaltSelection,
  84.       PauseSelection,
  85.       ResumeSelection,
  86.       HideApplication,
  87.       ShowApplication,
  88.       GetAppIcon
  89.       }; 
  90.   
  91.   xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, 0);            /* Initialize XView. */
  92.   INSTANCE = xv_unique_key(); 
  93.   canvasKeyData = xv_unique_key();                    /* Create data key to store image numbers in popup canvases */
  94.   theDisp = NULL;
  95.   for (i=0; i<NumColors; i++)
  96.     cmap[i] = 0;
  97.   for (i = 0; i < MaxNumSlides; i++)                    /* Allocate space for all the slides */
  98.   {
  99.     slide[i] = (SCR)malloc(sizeof(struct SlideStruct));
  100.     InitSlide(slide[i]);
  101.   }
  102.   
  103.   /*
  104.    * Initialize user interface components.
  105.    */
  106.   baseWindow = DisplayTool_baseWindow_objects_initialize(NULL, NULL);
  107.   infoPopup = DisplayTool_infoPopup_objects_initialize(NULL, baseWindow->baseWindow);
  108.   resizePopup = DisplayTool_resizePopup_objects_initialize(NULL, baseWindow->baseWindow);
  109.   helpPopup = DisplayTool_helpPopup_objects_initialize(NULL, baseWindow->baseWindow);
  110.   slidePopup = DisplayTool_slidePopup_objects_initialize(NULL, baseWindow->baseWindow);
  111.   slideNumberPopup = DisplayTool_slideNumberPopup_objects_initialize(NULL, baseWindow->baseWindow);
  112.   strcpy(currentFilename, "untitled");
  113.   imagesPerRow = xv_get(baseWindow->gallery, XV_WIDTH)/102;
  114.   CreateBrowse(OpenHandler, SaveHandler, baseWindow->baseWindow);      
  115.   notify_interpose_destroy_func(baseWindow->baseWindow, QuitNotify);
  116.   cms = (Cms)xv_create(NULL, CMS, CMS_SIZE, cmsSize, 
  117.                CMS_COLORS, colors, NULL);
  118.   listFont = (Xv_font) xv_find(baseWindow->baseWindow, FONT,
  119.                    FONT_FAMILY, FONT_FAMILY_LUCIDA_FIXEDWIDTH,
  120.                    FONT_STYLE, FONT_STYLE_NORMAL,
  121.                    FONT_SIZE, 12,
  122.                    NULL);
  123.   
  124.   /*
  125.    *    Set input mask
  126.    */
  127.   xv_set(canvas_paint_window(baseWindow->gallery),
  128.      WIN_CONSUME_EVENTS,
  129.      WIN_NO_EVENTS, LOC_DRAG, WIN_MOUSE_BUTTONS, NULL,
  130.          NULL);
  131.   
  132.   xv_set(baseWindow->gallery,
  133.      CANVAS_HEIGHT, 4*MaxNumImages,
  134.      CANVAS_AUTO_EXPAND, FALSE,
  135.      CANVAS_AUTO_SHRINK, FALSE, 
  136.      OPENWIN_AUTO_CLEAR, FALSE,  
  137.      NULL);
  138.   
  139.   galleryScrollbar = xv_create(baseWindow->gallery, SCROLLBAR,
  140.                    SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
  141.                    SCROLLBAR_PIXELS_PER_UNIT, 104,
  142.                    SCROLLBAR_OBJECT_LENGTH, MaxNumSlides/2,
  143.                    SCROLLBAR_PAGE_LENGTH, 1,
  144.                    SCROLLBAR_VIEW_LENGTH,3,
  145.                    NULL);
  146.   
  147.   xv_set(canvas_paint_window(baseWindow->slides),
  148.      WIN_CONSUME_EVENTS,
  149.      WIN_NO_EVENTS, LOC_DRAG, WIN_MOUSE_BUTTONS, NULL,
  150.          NULL);
  151.  
  152.   xv_set(baseWindow->slides,
  153.      CANVAS_HEIGHT, SmallHeight*(MaxNumSlides/SlidesPerRow),
  154.      CANVAS_AUTO_EXPAND, FALSE,
  155.      CANVAS_AUTO_SHRINK, FALSE,       
  156.      OPENWIN_AUTO_CLEAR, FALSE,  
  157.      NULL);
  158.   
  159.   slidesScrollbar = xv_create(baseWindow->slides, SCROLLBAR,
  160.                   SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
  161.                   SCROLLBAR_PIXELS_PER_UNIT, SmallHeight,
  162.                   SCROLLBAR_OBJECT_LENGTH, MaxNumSlides/SlidesPerRow,
  163.                   SCROLLBAR_PAGE_LENGTH, 1,
  164.                   SCROLLBAR_VIEW_LENGTH, 2,
  165.                   NULL);
  166.   
  167.   pixelValues = (unsigned long *)xv_get(cms, CMS_INDEX_TABLE);
  168.   
  169.   display = (Display *)xv_get(baseWindow->baseWindow, XV_DISPLAY);
  170.   galleryWin = (Window)xv_get(canvas_paint_window(baseWindow->gallery), XV_XID);
  171.   slidesWin = (Window)xv_get(canvas_paint_window(baseWindow->slides), XV_XID);
  172.   slidesCmap = DefaultColormap(display, DefaultScreen(display));
  173.   galleryCmap = DefaultColormap(display, DefaultScreen(display));
  174.   
  175.   theCmap   = galleryCmap;
  176.   theDisp   = display;
  177.   theScreen = DefaultScreen(theDisp);
  178.   rootW     = RootWindow(theDisp,theScreen);
  179.   theGC     = DefaultGC(theDisp,theScreen);
  180.   theVisual = DefaultVisual(theDisp,theScreen);
  181.   dispWIDE  = DisplayWidth(theDisp,theScreen);
  182.   dispHIGH  = DisplayHeight(theDisp,theScreen);
  183.   dispDEEP  = DisplayPlanes(theDisp,theScreen);
  184.   XSetLineAttributes(display, theGC, 2, LineSolid, CapProjecting, JoinMiter);
  185.   borderOffset = BorderOffset + xv_get(baseWindow->borderControls, XV_HEIGHT);
  186.   
  187.   CreateCursor();                            /* Create the busy and normal cursors */
  188.  
  189.   for (i = 0; i < MaxNumImages; i++)                    /* Initialize pointers to Frames and Canvases that... */
  190.   {                                    /* ...display full-sized images */
  191.     globalPopup[i] = (Frame)NULL;
  192.     globalCanvas[i] = (Canvas)NULL;
  193.     oldPopups[i] = (Frame)NULL;
  194.     oldCanvases[i] = (Canvas)NULL;
  195.   }
  196.   senderPort.hostName = "localhost";                    /* Networking stuff */
  197.   ReceiverPortNumber = AnyPort;
  198.   verbose = 0;
  199.   CheckOptions(argc, argv);
  200.   
  201.   senderPort.portNumber = PortMgrPortNumber;
  202.   sender = NewSender(&senderPort);
  203.   if (!sender)
  204.     {
  205.       notice_prompt(baseWindow->baseWindow, NULL,
  206.             NOTICE_MESSAGE_STRINGS,
  207.             "The PortManager is not running.",
  208.             "Please check that it is running and try again.",
  209.             NULL,
  210.             NOTICE_BUTTON_YES, "OK",
  211.             NULL);
  212.       exit(0);
  213.     }
  214.   receiver = NewReceiver(sender, "DisplayTool", ReceiverPortNumber);
  215.   if (verbose)
  216.     printf("Listening on port %d.\n", receiver->transport->xp_port);
  217.   
  218.   BuildDispatchTable (&DT);
  219.   canonFilename = (char *) malloc(MaxLength);
  220.   
  221.   (void) notify_enable_rpc_svc (TRUE);
  222.   
  223.   xv_set(slidePopup->duration, PANEL_VALUE, "Indefinite", NULL);
  224.   xv_set(baseWindow->baseWindow, XV_LABEL, 
  225.      "DisplayTool Document :  \"untitled\"", NULL);
  226.   xv_set(baseWindow->showFullSize, PANEL_VALUE, 2, NULL);
  227.   if (argc > 1)
  228.     for (i=1; i<argc; i++)
  229.       if (!strncmp(argv[i], "-h", 2) || !strncmp(argv[i], "-p", 2) )
  230.     i++;
  231.       else if (strncmp(argv[i], "-v", 2))
  232.     if ((fp=fopen(realpath(argv[i], dummy), "r")) != NULL)
  233.       {
  234.         fgets(header, strlen(firstLine)+1, fp);
  235.         header[strlen(firstLine)+1] = '\0';
  236.         if (!strncmp(header, firstLine, strlen(firstLine)))
  237.           OpenHandler(realpath(argv[i], dummy), 1);
  238.         else
  239.           LoadGalleryImage(realpath(argv[i], dummy));
  240.         fclose(fp);
  241.       }
  242.   timer.it_value.tv_usec = 250000;
  243.   timer.it_interval.tv_usec = 250000;
  244.   xv_main_loop(baseWindow->baseWindow);                    /* Turn control over to XView. */
  245.   exit(0);
  246. }                                    /* end function main */
  247.  
  248.  
  249.  
  250. /*
  251.  * Menu handler for `DocumentMenu (Info)'.
  252.  */
  253. Menu_item 
  254.   Info(Menu_item item, Menu_generate op)
  255. {
  256.   static int    first = TRUE;
  257.   static    Rect    rect;
  258.   
  259.   if (first == TRUE)
  260.     frame_get_rect(infoPopup->infoPopup, &rect);
  261.   if (op == MENU_NOTIFY)
  262.     if ((int)xv_get(infoPopup->infoPopup, XV_SHOW) == FALSE && first)               
  263.       {
  264.     ShowPopup(&infoPopup->infoPopup, 300, 170, rect.r_width, rect.r_height);
  265.     first = FALSE;
  266.       }
  267.     else
  268.       ShowPopup(&infoPopup->infoPopup, None, None, rect.r_width, rect.r_height);
  269.   return item;
  270. }
  271.  
  272. /*
  273.  * Menu handler for `DocumentMenu (Quit)'.
  274.  */
  275. Menu_item
  276.   QuitDisplayTool(Menu_item item, Menu_generate op)
  277. {
  278.   int i;
  279.   if (op == MENU_NOTIFY)
  280.     {
  281.       KillPopups();
  282.       xv_destroy_safe(baseWindow->baseWindow);
  283.     }
  284.   return item;
  285. }
  286.  
  287. /*
  288.  * Menu handler for `imagesMenu (Load Images)'.
  289.  */
  290. Menu_item
  291.   LoadImages(Menu_item item, Menu_generate op)
  292. {
  293.   if (op == MENU_NOTIFY)
  294.     Browse(getwd(dummy), BrowseMultiple, NULL, NULL, NULL);
  295.   return item;
  296. }
  297.  
  298. /*
  299.  * Menu handler for `imagesMenu (Clear Selected Images)'.
  300.  */
  301. Menu_item
  302.   ClearSelectedImages(Menu_item item, Menu_generate op)
  303. {
  304.   if (op == MENU_NOTIFY)
  305.     printf("Not implemented yet\n");
  306.   return item;
  307. }
  308.  
  309.  
  310. /*
  311.  * Menu handler for `imagesMenu (Clear Gallery)'.
  312.  */
  313. Menu_item
  314.   ClearGallery(Menu_item item, Menu_generate op)
  315. {
  316.   int i;
  317.   if (op == MENU_NOTIFY)
  318.     {
  319.       theCmap = galleryCmap;
  320.       theDisp = display;
  321.       for (i=0; i<numGalleryImages; i++)
  322.       {
  323.     if (dtImage[i]->galleryImage != (XImage*)NULL)
  324.     {
  325.       XDestroyImage(dtImage[i]->galleryImage);
  326.       dtImage[i]->galleryImage = NULL;
  327.     }
  328.       }
  329.       numGalleryImages = 0;
  330.       GalleryRepaint(NULL, NULL, NULL, NULL);
  331.     }
  332.   return item;
  333. }
  334.  
  335.  
  336. /*
  337.  * Menu handler for `documentMenu (Open)'.
  338.  */
  339. Menu_item
  340.   OpenSequence(Menu_item item, Menu_generate op)
  341. {
  342.   if (op == MENU_NOTIFY)
  343.     Browse(NULL, BrowseOpen, 1, "#DisplayTool Document#", "DisplayTool");
  344.   return item;
  345. }
  346.  
  347. /*
  348.  * Menu handler for `documentMenu (Help)'.
  349.  */
  350. Menu_item
  351.   Help(Menu_item item, Menu_generate op)
  352. {
  353.   static int    first = TRUE;
  354.   static    Rect    rect;
  355.   
  356.   if (first == TRUE)
  357.     frame_get_rect(helpPopup->helpPopup, &rect);
  358.   if (op == MENU_NOTIFY)
  359.     if ((int)xv_get(helpPopup->helpPopup, XV_SHOW) == FALSE && first)
  360.       {
  361.     ShowPopup(&helpPopup->helpPopup, 300, 170, rect.r_width, rect.r_height);
  362.     first = FALSE;
  363.       }
  364.     else
  365.       ShowPopup(&helpPopup->helpPopup, None, None, rect.r_width, rect.r_height);
  366.   return item;
  367. }
  368.  
  369.  
  370. /*
  371.  * Menu handler for `documentMenu (Save Sequence)'.
  372.  */
  373. Menu_item
  374.   SaveSequence(Menu_item item, Menu_generate op)
  375. {
  376.   if (op == MENU_NOTIFY)
  377.     if (strlen(currentFilename) > 0 &&
  378.     strstr(currentFilename, "untitled") == NULL)
  379.       Browse(currentFilename, BrowseCheckSave, NULL, "#DisplayTool Document#", "DisplayTool"); 
  380.     else
  381.       Browse(getwd(dummy), BrowseSave, NULL, "#DisplayTool Document#", "DisplayTool");
  382.   return item;
  383. }
  384.  
  385.  
  386. /*
  387.  * Menu handler for `documentMenu (Save Sequence As)'.
  388.  */
  389. Menu_item
  390.   SaveSequenceAs(Menu_item item, Menu_generate op)
  391. {
  392.   if (op == MENU_NOTIFY)
  393.     Browse(getwd(dummy), BrowseSave, NULL, "#DisplayTool Document#", "DisplayTool");
  394.   return item;
  395. }
  396.  
  397. /*
  398.  * Menu handler for `documentMenu (Close)'.
  399.  */
  400. Menu_item
  401.   Close(Menu_item item, Menu_generate op)
  402. {
  403.   if (op == MENU_NOTIFY)
  404.     printf("Not implemented yet\n");
  405.   return item;
  406. }
  407.  
  408. /*
  409.  * Menu handler for `slidesMenu (Insert Slide)'.
  410.  */
  411. Menu_item
  412.   InsertNewSlide(Menu_item item, Menu_generate op)
  413. {
  414.   int    i;
  415.   int    notifyFlag = 0;
  416.   char    errorMessage[MaxLength];
  417.   
  418.   if (op == MENU_NOTIFY)
  419.     {
  420.       for (i=0; i < numSlidesImages; i++)
  421.     {
  422.       if (dtImage[i]->slide >= selectedSlide)
  423.         if (dtImage[i]->slide < MaxNumSlides-1)
  424.           dtImage[i]->slide = dtImage[i]->slide+1;
  425.         else
  426.           {
  427.         dtImage[i]->slide = MaxNumSlides-1;
  428.         notifyFlag = 1;
  429.           }
  430.     }
  431.       if ((int)item != (int)baseWindow->baseWindow) 
  432.     SlidesRepaint(NULL, NULL, NULL, NULL);
  433.       if (notifyFlag)
  434.     {
  435.       sprintf(errorMessage, "Can't exceed %d slides.", MaxNumSlides);
  436.       notice_prompt(baseWindow->baseWindow, NULL,
  437.             NOTICE_MESSAGE_STRINGS,
  438.             errorMessage,
  439.             " ",
  440.             "Images beyond this limit shall",
  441.             "be placed in the last slide.",
  442.             NULL,
  443.             NOTICE_BUTTON_YES, "OK",
  444.             NULL);
  445.       return(item);
  446.     }
  447.       changes = True;
  448.       UpdateHeader(True);
  449.       SetTotalNumberOfSlides();
  450.     } 
  451.   return(item);
  452. }                                    /* end function InsertNewSlide */
  453.  
  454. /*
  455.  * Menu handler for `slidesMenu (Slide Info ...)'.
  456.  */
  457. Menu_item
  458.   SlideInfo(Menu_item item, Menu_generate op)
  459. {
  460.   static int    first = TRUE;
  461.   static    Rect    rect;
  462.   
  463.   if (first == TRUE)
  464.     frame_get_rect(slidePopup->slidePopup, &rect);
  465.   if (op == MENU_NOTIFY)
  466.     {
  467.       if ((int)xv_get(slidePopup->slidePopup, XV_SHOW) == FALSE && first)          
  468.     {
  469.       ShowPopup(&slidePopup->slidePopup, 300, 170, rect.r_width, rect.r_height);
  470.       first = FALSE;
  471.     }
  472.       else
  473.     ShowPopup(&slidePopup->slidePopup, None, None, rect.r_width, rect.r_height);
  474.       SetCurrentSlide(selectedSlide+1);
  475.     }
  476.   return item;
  477. }
  478.  
  479.  
  480.  
  481. /*
  482.  * Menu handler for `slidesMenu (Refresh Slides)'.
  483.  */
  484. Menu_item
  485.   RedrawSlides(Menu_item item, Menu_generate op)
  486. {
  487.   if (op == MENU_NOTIFY)
  488.     SlidesRepaint(NULL, NULL, NULL, NULL);
  489.   return item;
  490. }
  491.  
  492.  
  493.  
  494. /*
  495.  * Menu handler for `slidesMenu (Clear All)'.
  496.  */
  497. Menu_item
  498.   ClearAll(Menu_item item, Menu_generate op)
  499. {
  500.   int    i;
  501.   IMAGE    tempImage;
  502.   
  503.   if (op == MENU_NOTIFY)
  504.     {
  505.       if (NotifyChoice(baseWindow->baseWindow,
  506.                "Are you sure you want to clear all the images in all the slides?") == Cancel)
  507.     return item;
  508.       theCmap = slidesCmap;
  509.       theDisp = display;
  510.       for (i=0; i<numClipboardImages; i++)
  511.     FreeImage(clipboardImage[i]); 
  512.       numClipboardImages = 0;
  513.       for (i=0; i<MaxNumSlides; i++)
  514.     {
  515.       if (slide[i]->duration != NULL)
  516.         free((char *)slide[i]->duration);
  517.       if (slide[i]->label != NULL)
  518.         free((char *)slide[i]->label);
  519.       slide[i]->duration = NULL;
  520.       slide[i]->label = NULL;
  521.       slide[i]->numberOfImages = 0;
  522.     }
  523.       for (i=0; i < numSlidesImages; i++)
  524.       {
  525.     tempImage = dtImage[i];
  526.     if (tempImage->slideImage != (XImage*)NULL)
  527.     {
  528.       XDestroyImage(tempImage->slideImage);
  529.       tempImage->slideImage = NULL;
  530.     }
  531.     if (tempImage->largeImage != (XImage*)NULL)
  532.     {
  533.       XDestroyImage(tempImage->largeImage);
  534.       tempImage->largeImage = NULL;
  535.     }
  536.       }
  537.       numSlidesImages = 0;
  538.       SlidesRepaint(NULL, NULL, NULL, NULL);
  539.       changes = True;
  540.       UpdateHeader(True);
  541.       SetTotalNumberOfSlides();
  542.       RedrawRectangles();
  543.     }
  544.   return item;
  545. }                                    /* end function ClearAll */
  546.  
  547.  
  548. /*
  549.  * Event callback function for `duration'.
  550.  */
  551. void
  552.   DurationEventProc(Panel_item item, Event *event)
  553. {
  554.   if (event_is_up(event) && event_is_ascii(event))
  555.     slide[selectedSlide]->duration = 
  556.       (char *)strdup((char *)xv_get(slidePopup->duration, PANEL_VALUE));
  557.   changes = True;
  558.   UpdateHeader(True);
  559.   panel_default_handle_event(item, event);
  560. }
  561.  
  562.  
  563. /*
  564.  * Event callback function for `label'.
  565.  */
  566. void
  567.   LabelEventProc(Panel_item item, Event *event)
  568. {
  569.   if (event_is_up(event) && event_is_ascii(event))
  570.     {
  571.       if (strlen((char *)xv_get(slidePopup->label, PANEL_VALUE)) > 0)
  572.     slide[selectedSlide]->label = 
  573.       (char *)strdup((char *)xv_get(slidePopup->label, PANEL_VALUE));
  574.       else
  575.     slide[selectedSlide]->label = (char *)strdup("No Label");
  576.     }
  577.   changes = True;
  578.   UpdateHeader(True);
  579.   panel_default_handle_event(item, event);
  580. }
  581.  
  582.  
  583. /*
  584.  * Notify callback function for `indefiniteButton'.
  585.  */
  586. /* ARGSUSED */
  587. void
  588.   Indefinite(Panel_item item, Event *event)
  589. {
  590.   xv_set(slidePopup->duration, PANEL_VALUE, "Indefinite", NULL);
  591.   slide[selectedSlide]->duration = (char *)strdup("Indefinite");
  592.   changes = True;
  593.   UpdateHeader(True);
  594. }
  595.  
  596.  
  597. /*
  598.  * Notify callback function for `showFullSize'.
  599.  */
  600. /* ARGSUSED */
  601. void
  602.   ShowFullSize(Panel_item item, int value, Event *event)
  603. {
  604.   char temp[MaxLength];
  605.   if (slideSize == Small)
  606.     {
  607.       xv_set(baseWindow->showFullSize, PANEL_VALUE, 1, NULL);
  608.       slideSize = Large;
  609.     }
  610.   else
  611.     {
  612.       xv_set(baseWindow->showFullSize, PANEL_VALUE, 2, NULL);      
  613.       KillPopups();
  614.       slideSize = Small;
  615.     }
  616.   if (slideSize == Small)
  617.     {
  618.       if (slideSize == Small)
  619.     {
  620.       previousSlide = selectedSlide;
  621.       selectedSlide = 0;
  622.     }
  623.       if ((int)xv_get(slidesScrollbar, SCROLLBAR_VIEW_START) != selectedSlide)
  624.     xv_set(slidesScrollbar, SCROLLBAR_VIEW_START, selectedSlide, NULL); 
  625.       SetCurrentSlide(selectedSlide+1);
  626.       xv_set(slidePopup->duration, PANEL_VALUE, slide[selectedSlide]->duration, NULL);
  627.       if (slide[selectedSlide]->label)
  628.     if (strncmp(slide[selectedSlide]->label, "No Label", 8) != 0)
  629.       xv_set(slidePopup->label, PANEL_VALUE, slide[selectedSlide]->label, NULL);
  630.     else
  631.       xv_set(slidePopup->label, PANEL_VALUE, "", NULL);
  632.       SlidesRepaint(NULL, NULL, NULL, NULL);
  633.     }
  634.   else
  635.     {
  636.       beginDoubleBuffer = 1;
  637.       sprintf(temp, "Current Slide    # %d", selectedSlide+1);
  638.       PrepareMultipleWindowsForDisplay(selectedSlide);
  639.       DisplayMultipleWindows(selectedSlide);
  640.     }
  641.   CheckGeometry();
  642. }                                    /* end function ShowFullSize */
  643.  
  644.  
  645.  
  646. IMAGE
  647.   CreateImage(char *file)
  648. {
  649.   IMAGE        image = (IMAGE)NULL;
  650.   int        i;
  651.   
  652.   sprintf(diagString, "Entering CreateImage with filename %s.\n",
  653.       file);
  654.   PrintDTDiagnostics(diagString);
  655.   image = xvimage_main(file);                        /* Try to create a new image */
  656.   if (image == (IMAGE)NULL)                        /* Did the attempt fail? */
  657.     return((IMAGE)NULL);                        /* Yes, return a null IMAGE, don't do anything else */
  658.   if (verbose)
  659.     printf("CREATEIMAGE: width=%d height=%d\n", image->origWidth, image->origHeight);
  660.   image->largeWidth = image->origWidth;
  661.   image->largeHeight = image->origHeight;
  662.   for (i=0; i<numcols && i<=NumColors; i++)
  663.     image->cols[i] = cols[i];
  664.   image->numcols = numcols;
  665.   image->nfcols = nfcols;
  666.   for (i=0; i<nfcols && i<=NumColors; i++)
  667.   {
  668.     image->freecols[i] = freecols[i];
  669.     cmap[(int)image->freecols[i]]++;
  670.   }
  671.   sprintf(diagString, "In CreateImage, format = %s\n", image->format);
  672.   PrintDTDiagnostics(diagString);
  673.   return(image);   
  674. }                                    /* end function CreateImage */
  675.  
  676.  
  677.  
  678. IMAGE ReCreateImage(IMAGE image)
  679. {
  680.   IMAGE        tempImage = (IMAGE)NULL;
  681.   int        tempSlide, width, height;
  682.   XPoint    corner;
  683.   
  684.   sprintf(diagString, "Entered ReCreateImage, creating image (file: %s) on demand.\n",
  685.       image->filename);
  686.   PrintDTDiagnostics(diagString);
  687.   width = image->largeWidth;
  688.   height = image->largeHeight;
  689.   corner.x = image->corner.x;
  690.   corner.y = image->corner.y;
  691.   tempSlide = image->slide;
  692.   
  693.   tempImage = CreateImage(image->filename);                /* Create a new image for this file */
  694.   if (tempImage == (IMAGE)NULL)                        /* Did the image creation fail? */
  695.   {                                    /* Yes, print a diagnostic message and return */
  696.     sprintf(diagString, "In PaintSlide, could not create new image for file %s.\n",
  697.         image->filename);
  698.     PrintDTDiagnostics(diagString);
  699.     return((IMAGE)NULL);
  700.   }
  701.   tempImage->largeWidth = width;                    /* Restore crucial values to newly-created IMAGE structure */
  702.   tempImage->largeHeight = height;
  703.   tempImage->corner.x = corner.x;
  704.   tempImage->corner.y = corner.y;
  705.   tempImage->slide = tempSlide;
  706.   return(tempImage);
  707. }                                    /* end function ReCreateImage */
  708.  
  709.  
  710.  
  711. void 
  712.   ShowPopup(Frame *popup, int cornerx, int cornery, int width, int height)
  713. {
  714.   Rect rect;
  715.   if (cornerx >= 0 && cornery >= 0)
  716.     {
  717.       sprintf(diagString,"ShowPopup: x=%d y=%d w=%d h=%d popup=%d\n",
  718.           cornerx, cornery, width, height, *popup);
  719.       PrintDTDiagnostics(diagString);
  720.       rect.r_left = cornerx;
  721.       rect.r_top = cornery;
  722.       rect.r_width = width;
  723.       rect.r_height = height;
  724.       frame_set_rect(*popup, &rect);
  725.     }
  726.   if ((int)xv_get(*popup, FRAME_CMD_PUSHPIN_IN) == FALSE)           
  727.     xv_set(*popup, FRAME_CMD_PUSHPIN_IN, TRUE, NULL);           
  728.   if ((int)xv_get(*popup, XV_SHOW) == FALSE)               
  729.     xv_set(*popup, XV_SHOW, TRUE, NULL);               
  730.   XRaiseWindow(display, (Window)xv_get(*popup, XV_XID));
  731.   XFlush(display);
  732.   PrintDTDiagnostics("Leaving ShowPopup.\n");
  733. }    
  734.  
  735. void 
  736.   HidePopup(Frame *popup)
  737. {
  738.   sprintf(diagString,"HidePopup: popup=%d\n", *popup);
  739.   PrintDTDiagnostics(diagString);
  740.   xv_set (*popup, FRAME_CMD_PUSHPIN_IN, FALSE, NULL);           
  741.   xv_set (*popup,XV_SHOW, FALSE, NULL);               
  742. /*
  743.   if ((int)xv_get(*popup,FRAME_CMD_PUSHPIN_IN) == TRUE)           
  744.     xv_set (*popup, FRAME_CMD_PUSHPIN_IN, FALSE, NULL);           
  745.   if ((int)xv_get(*popup, XV_SHOW) == TRUE)               
  746.     xv_set (*popup,XV_SHOW, FALSE, NULL);               
  747. */
  748. }      
  749.  
  750.  
  751.  
  752. void
  753.   GetEffectiveDimensions(IMAGE tempImage, int *width, int *height)  /* Given an image, determine the width and height... */
  754. {                                    /* ...necessary to make it fit into a slide for display */
  755.   if (slideSize == Small)
  756.   {
  757.     if (tempImage->corner.x%SmallWidth +                /* Would this image run off the right side of the... */
  758.     (tempImage->largeWidth / largeFactor) > SmallWidth-2)        /* ...slide? */
  759.       *width = SmallWidth - 2 - tempImage->corner.x%SmallWidth;        /* Yes, adjust the width to make the slide fit */
  760.     if (tempImage->corner.y%SmallHeight +                /* Same test for height: would this image run off the... */
  761.     (tempImage->largeHeight / largeFactor) > SmallHeight-2)        /* ...bottom of the slide? */
  762.       *height = SmallHeight - 2  - tempImage->corner.y%SmallHeight; /* Yes, truncate the height to make the slide fit */
  763.   }
  764.   else                                    /*  slideSize == Large */
  765.   {
  766.     *width = tempImage->largeWidth / largeFactor;
  767.     *height = tempImage->largeHeight / largeFactor;
  768.     return;
  769.   }
  770. }                                    /* end function GetEffectiveDimensions */
  771.  
  772.  
  773. void
  774.   CopyImage(IMAGE srcImage, IMAGE destImage)                /* Assumes "destImage" is always a dtImage */
  775. {
  776.   int    i;
  777.   
  778.   if (srcImage == destImage)                        /* Nothing to copy; images are identical */
  779.     return;
  780.   if (destImage == (IMAGE)NULL)
  781.   {
  782.     PrintDTDiagnostics("In CopyImage, destImage was NULL.\n");
  783.     return;
  784.   }
  785.   if (destImage->filename != (char*)NULL)                /* Begin copying data from "srcImage" to "destImage" */
  786.     free(destImage->filename);
  787.   destImage->filename = (char *)strdup(srcImage->filename);
  788.   if (destImage->format != (char*)NULL)
  789.     free(destImage->format);
  790.   destImage->format = (char *)strdup(srcImage->format);
  791.   destImage->corner.x = srcImage->corner.x;
  792.   destImage->corner.y = srcImage->corner.y;
  793.   if (destImage->imageData != (byte*)NULL)                /* Is there already space allocated for the destination's... */
  794.   {                                    /* image data? */
  795.     if ((destImage->origWidth * destImage->origHeight) <        /* Is the destination image data too small? */
  796.     (srcImage->origWidth * srcImage->origHeight))
  797.     {                                    /* Yes, free up old space and allocate enough for the... */
  798.       free(destImage->imageData);                    /* ...new image data */
  799.       destImage->imageData = (byte*)MyMalloc(srcImage->origWidth *
  800.                          srcImage->origHeight);
  801.     }
  802.   }
  803.   bcopy(srcImage->imageData, destImage->imageData,            /* Copy the original image's data into the new image */
  804.     srcImage->origWidth * srcImage->origHeight);
  805.   destImage->origWidth = srcImage->origWidth;
  806.   destImage->origHeight = srcImage->origHeight;
  807.   
  808.   if (destImage->slideImage != (XImage*)NULL)                /* Re-create the slide image (this is inefficient: a... */
  809.     XDestroyImage(destImage->slideImage);                /* ...bcopy of the appropriate information from the... */
  810.   destImage->slideImage = Resize(destImage->imageData,            /* ...srcImage would be much better if it exists) */
  811.                  destImage->origWidth,
  812.                  destImage->origHeight,
  813.                  srcImage->largeWidth / largeFactor,
  814.                  srcImage->largeHeight / largeFactor);
  815.   destImage->largeWidth = srcImage->largeWidth;
  816.   destImage->largeHeight = srcImage->largeHeight;
  817.   
  818.   for (i=0; i<srcImage->numcols && i<=NumColors; i++)
  819.     destImage->cols[i] = srcImage->cols[i];
  820.   destImage->numcols = srcImage->numcols;
  821.   destImage->nfcols = srcImage->nfcols;
  822.   for (i=0; i<srcImage->nfcols && i<=NumColors; i++)
  823.     {
  824.       destImage->freecols[i] = srcImage->freecols[i];  
  825.       cmap[(int)destImage->freecols[i]]++;
  826.     }
  827. }                                    /* end function CopyImage */
  828.  
  829.  
  830.  
  831. void
  832.   FreeImage(IMAGE image)
  833. {
  834.   if (image == (IMAGE)NULL)
  835.     return;
  836.   FreeColors(image);
  837.   if (image->filename != NULL)
  838.     {
  839.       free(image->filename);
  840.       image->filename = NULL;
  841.     }
  842.   if (image->format != NULL)
  843.     {
  844.       free(image->format);
  845.       image->format = NULL;
  846.     }
  847.   if (image->galleryImage != (XImage*)NULL)
  848.     {
  849.       XDestroyImage(image->galleryImage);
  850.       image->galleryImage = NULL;
  851.     }
  852.   if (image->slideImage != (XImage*)NULL)
  853.     {
  854.       XDestroyImage(image->slideImage);
  855.       image->slideImage = NULL;
  856.     }
  857.   if (image->largeImage != (XImage*)NULL)
  858.     {
  859.       XDestroyImage(image->largeImage);
  860.       image->largeImage = NULL;
  861.     }
  862.   if (image->imageData != (byte*)NULL)
  863.     {
  864.       free((char *)image->imageData);
  865.       image->imageData = (byte*)NULL;
  866.     }
  867.   free((char *)image);
  868.   image = (IMAGE)NULL;
  869. }                                    /* end function FreeImage */
  870.  
  871.  
  872. void
  873.   SetTotalNumberOfSlides(void)
  874. {
  875.   int maxSlide;
  876.   char temp[MaxLength];
  877.   maxSlide = GetMaxSlide();
  878.   if (numSlidesImages > 0)
  879.     {
  880.       sprintf(temp, "Total Number of Slides :  %d", maxSlide + 1);
  881.       xv_set(baseWindow->totalNumberOfSlidesMessage, PANEL_LABEL_STRING, temp, NULL);
  882.     }
  883.   else 
  884.     {
  885.       xv_set(baseWindow->totalNumberOfSlidesMessage, PANEL_LABEL_STRING, 
  886.          "Total Number of Slides :  0", NULL);
  887.     }
  888. }
  889.  
  890.  
  891. int 
  892.   GetMaxSlide(void)
  893. {
  894.   int i, maxSlide = 0;
  895.   for (i=0; i<numSlidesImages; i++)
  896.     {
  897.       if (dtImage[i]->slide > maxSlide)
  898.     maxSlide = dtImage[i]->slide;
  899.     }
  900.   return maxSlide;
  901. }
  902.  
  903.  
  904. void
  905.   FreeColors(IMAGE image)
  906. {
  907.   int i;
  908.   int count = 0;
  909.   
  910.   for (i=0; i<image->nfcols; i++) 
  911.     {
  912.       /*      if (i==image->nfcols-1)
  913.           printf("cmap[image->freecols[nfcols-1]]=%d\n", cmap[(int)image->freecols[i]]);  */
  914.       if (cmap[(int)image->freecols[i]]--==1)   
  915.     {
  916.       XFreeColors(theDisp, theCmap, image->freecols + i, 1, 0L);
  917.       sprintf(diagString, "f%d ", (int)image->freecols[i]);
  918.       PrintDTDiagnostics(diagString);
  919.       count++;
  920.     }
  921.       else if (cmap[(int)image->freecols[i]] < 0)
  922.     cmap[(int)image->freecols[i]] = 0;
  923.     }
  924.   if (verbose)
  925.     {
  926.       printf("\nFreed %d colors for %s   nfcols = %d\n", count, image->filename, image->nfcols);
  927.       PrintCmap();
  928.     }
  929. }                                    /* end function FreeColors */
  930.  
  931.  
  932.  
  933.  
  934. /*
  935.   This is the interpose function for the frame destroy procedure.  It
  936.   is called when the quit button is pressed, or when the frame's "Quit"
  937.   menu selection is chosen.
  938.   The frame destroying process happens in two phases (meaning this
  939.   function will be called twice).  The first time it is called, status =
  940.   DESTROY_CHECKING (this is done automatically by XView).  At this
  941.   point, the interpose function can choose to veto the destruction, or
  942.   let it proceed to phase two, where the actual destruction occurs.
  943.   */
  944. Notify_value 
  945.   QuitNotify(Notify_client client, Destroy_status status)
  946. {
  947.   /* First phase:  Check to see if we really want to destroy the frame */
  948.   if (status == DESTROY_CHECKING)
  949.     {
  950.       if (CheckChanges(client) == CancelQuit)
  951.     return notify_veto_destroy(client);
  952.     }
  953.   else /* Second phase:  Proceed to destroy */
  954.     {
  955.       SenderDisconnectFromPortMgr(sender, &(receiver->receivePort));
  956.       return notify_next_destroy_func(client, status);
  957.     } 
  958.   return NOTIFY_DONE;
  959. }
  960.  
  961.  
  962.  
  963. int
  964.   CheckChanges(Notify_client client)
  965. {
  966.   int    response;
  967.   char    message[MaxLength];
  968.   
  969.   if (changes == 0)                            /* No changes, it's okay to quit right now */
  970.     return(~CancelQuit);
  971.   sprintf(message, "Save changes to '%s' ?", currentFilename);
  972.   response = notice_prompt(baseWindow->baseWindow, NULL,
  973.                NOTICE_MESSAGE_STRINGS,
  974.                message,
  975.                NULL,
  976.                NOTICE_BUTTON_YES, "Yes",
  977.                NOTICE_BUTTON_NO,  "No",
  978.                NOTICE_BUTTON, "Cancel", 100,
  979.                NULL);
  980.   if (response == 100)
  981.     return(CancelQuit);
  982.   if (response == NOTICE_YES)
  983.   {
  984.     WriteSequenceToFile();
  985.     notify_veto_destroy(client);
  986.   }
  987.   return(~CancelQuit);
  988. }                                    /* end function CheckChanges */
  989.  
  990.  
  991.  
  992. /* 
  993.  * This function parses the command line and retrieves all the known options and their arguments.
  994.  * Currently, the two options are hostname and portnumber.
  995.  * After parsing the options, the variable optind will point to the start of those non-option arguments.  In this case, it will be the filename to be
  996.  * loaded.  At present, only one filename will be handled.  So if there are multiple filenames typed, the last one will be loaded.
  997.  */
  998. void CheckOptions(int argc, char **argv)
  999. {
  1000.   int optionChar;  
  1001.   int option_index = 0;
  1002.   static struct option long_options[] =
  1003.     {
  1004.       {"hostname", 1, 0, 'h'},        
  1005.       {"portnumber", 1, 0, 'p'},
  1006.       {"verbose", 0, 0, 'v'},
  1007.       {0, 0, 0, 0}
  1008.     };
  1009.   while (1)                                /* Start parsing all known options */
  1010.     {
  1011.       optionChar = getopt_long_only (argc, argv, "h:p:v",
  1012.                      long_options, &option_index);
  1013.       if (optionChar == EOF)                        /* Done with all known options */
  1014.     break;
  1015.       switch (optionChar)
  1016.     {
  1017.     case 'h':
  1018.       if (optarg) 
  1019.         senderPort.hostName = strdup(optarg);
  1020.       break;
  1021.     case 'p':
  1022.       if (optarg) 
  1023.         ReceiverPortNumber = atoi(optarg);
  1024.       break;
  1025.     case 'v':
  1026.       verbose = 1;
  1027.       printDiags = 1;
  1028.       break;
  1029.     default:
  1030.       break;
  1031.     }
  1032.     }
  1033. }
  1034.  
  1035. void
  1036.   DisplayImages(int slideNum)
  1037. {
  1038.   int        i, j, tempSlide, width, height;
  1039.   int        hold;
  1040.   XPoint    corner;
  1041.   IMAGE        tempImage;
  1042.   
  1043.   PrintDTDiagnostics("Entering DisplayImages.\n");
  1044.   for (i=0; i<slide[slideNum]->numberOfImages; i++)            /* Load all the images for this slide only */
  1045.   {
  1046.     j = slide[slideNum]->imageIds[i];                    /* Set j to one of this slide's images (the 'ith image) */
  1047.     width = dtImage[j]->largeWidth;
  1048.     height = dtImage[j]->largeHeight;
  1049.     corner.x = dtImage[j]->corner.x;
  1050.     corner.y = dtImage[j]->corner.y;
  1051.     tempSlide = dtImage[j]->slide;
  1052.     if (verbose)
  1053.       printf("filename = %s\n", dtImage[j]->filename);
  1054.     hold = numSlidesImages;
  1055.     numSlidesImages = 0; 
  1056.     if (dtImage[j]->imageData == (byte*)NULL)                /* Has the image data been read in yet? */
  1057.     {                                    /* No, read it in now, on demand */
  1058.       BusyApp();                            /* Tell XView that the app is occupied */
  1059.       tempImage = ReCreateImage(dtImage[j]);
  1060.       dtImage[j] = tempImage;
  1061.       NormalApp();                            /* Tell XView that the app is ready-to-go again */
  1062.     }
  1063.     else                                /* Yes, the image data has been read in already, so just... */
  1064.       tempImage = dtImage[j];                        /* ...point to it */
  1065.     
  1066.     if (AlreadyInSlidesBuffer(tempImage) == NotInBuffer)        /* Does this image have its slide image built yet? */
  1067.     {                                    /* No, build it */
  1068.       sprintf(diagString, "Slide %d (filename : %s) is not in the Slides buffer.\n",
  1069.           j, tempImage->filename);
  1070.       PrintDTDiagnostics(diagString);
  1071.       tempImage->slideImage = Resize(tempImage->imageData,
  1072.                      tempImage->origWidth,
  1073.                      tempImage->origHeight,
  1074.                      tempImage->origWidth / largeFactor,
  1075.                      tempImage->origHeight / largeFactor);
  1076.     }
  1077.     numSlidesImages = hold;
  1078.   }   
  1079. }                                    /* end function DisplayImages */
  1080.  
  1081.  
  1082.  
  1083. int
  1084.   AlreadyInSlidesBuffer(IMAGE tempImage)
  1085. {
  1086.   if (tempImage->slideImage == (XImage*)NULL)
  1087.     return(NotInBuffer);
  1088.   else
  1089.     return(0);
  1090.  
  1091.  
  1092.  
  1093. /*
  1094.  * Notify callback function for `DoneHandler'.
  1095.  */
  1096. /* ARGSUSED */
  1097. void
  1098.   DoneHandler(Panel_item item, Event *event)
  1099. {
  1100.   Panel panel = (Panel)xv_get(item, PANEL_PARENT_PANEL);
  1101.   Frame frame = (Frame)xv_get(panel, XV_OWNER);
  1102.   HidePopup(&frame);  
  1103. }
  1104.  
  1105.  
  1106. void
  1107.   PrintCmap(void)
  1108. {
  1109.   int i;
  1110.   
  1111.   printf("In PrintCmap, colormap is:\n");
  1112.   for (i=0; i< NumColors; i++)
  1113.     printf("%d ", cmap[i]);
  1114.   printf("\n\n");
  1115. }
  1116.  
  1117. void
  1118.   NullFields(IMAGE image)
  1119. {
  1120.   int    i;
  1121.   
  1122.   image->filename = NULL;
  1123.   image->format = NULL;
  1124.   image->origWidth = 0;
  1125.   image->origHeight = 0;
  1126.   image->largeWidth = 0;
  1127.   image->largeHeight = 0;
  1128.   image->galleryWidth = 0;
  1129.   image->galleryHeight = 0;
  1130.   image->imageData = (byte*)NULL;
  1131.   image->galleryImage = (XImage*)NULL;
  1132.   image->slideImage = (XImage*)NULL;
  1133.   image->largeImage = (XImage*)NULL;
  1134.   image->slide = 0;
  1135.   image->corner.x = 0;
  1136.   image->corner.y = 0;
  1137.   image->numcols = 0;
  1138.   image->nfcols = 0;
  1139.   for (i = 0; i < NumColors; i++)
  1140.      {
  1141.        image->cols[i] = 0;
  1142.        image->freecols[i] = 0;
  1143.      }
  1144. }                                    /* end function NullFields */
  1145.  
  1146.  
  1147. /* ARGSUSED */
  1148. Notify_value
  1149.   IncrementCounter(Notify_client client, int which)
  1150. {
  1151.   if (!pauseMode)
  1152.     {
  1153.       timeCount++;
  1154.       if (atoi(slide[selectedSlide]->duration))
  1155.     if ((timeCount-1)/4 >= atoi(slide[selectedSlide]->duration)) /* Subtract 1 from timeCount since it start counting from 0 */
  1156.       {
  1157.         KillPopups();
  1158.         notify_set_itimer_func((Notify_client)baseWindow->baseWindow,
  1159.                    NOTIFY_FUNC_NULL, ITIMER_REAL, NULL, NULL);
  1160.       }
  1161.     }
  1162.   return(NOTIFY_DONE);
  1163. }                                    /* end function IncrementCounter */
  1164.  
  1165.  
  1166.  
  1167. void
  1168.   CheckGeometry(void)
  1169. {
  1170.   Rect rect;
  1171.   if (dontCheckGeometry == 0)
  1172.     {
  1173.       /* Bry --      frame_get_rect(fullslidePopup->fullslidePopup, &rect);  */
  1174.       /*      printf("x=%d y=%d w=%d h=%d\n", rect.r_left, rect.r_top, rect.r_width, rect.r_height); 
  1175.           if (rect.r_left != slide[selectedSlide]->corner.x || rect.r_top != slide[selectedSlide]->corner.y ||
  1176.           rect.r_width != slide[selectedSlide]->width || rect.r_height != slide[selectedSlide]->height)
  1177.           {
  1178.           slide[selectedSlide]->corner.x = rect.r_left;
  1179.           slide[selectedSlide]->corner.y = rect.r_top;
  1180.           slide[selectedSlide]->width = rect.r_width;
  1181.           slide[selectedSlide]->height = rect.r_height;
  1182.           changes = True;
  1183.           UpdateHeader(True);
  1184.           printf("x=%d y=%d w=%d h=%d\n", rect.r_left, rect.r_top, rect.r_width, rect.r_height);
  1185.           }
  1186.           */
  1187.     }
  1188. }
  1189.  
  1190.  
  1191.  
  1192. void DisplayMultipleWindows(int slide)
  1193. {
  1194.   int        i, tot = 0;
  1195.   
  1196.   PrintDTDiagnostics("Entering DisplayMultipleWindows.\n");
  1197.   for (i=0; i<numSlidesImages; i++)
  1198.     if (dtImage[i]->slide == slide)
  1199.       {
  1200.     ShowPopup(&(globalPopup[tot]),
  1201.           (int)(largeFactor*(dtImage[i]->corner.x-2)),
  1202.           (int)(largeFactor*(dtImage[i]->corner.y-2)),
  1203.           dtImage[i]->largeWidth,
  1204.           dtImage[i]->largeHeight);
  1205.     tot++;
  1206.       }
  1207. }                                    /* end function DisplayMultipleWindows */
  1208.  
  1209.  
  1210.  
  1211. void PrepareMultipleWindowsForDisplay(int slide)
  1212. {
  1213.   int        i, tot = 0;
  1214.   IMAGE        tempImage;
  1215.   
  1216.   for (i=0; i<numSlidesImages; i++)
  1217.     if (dtImage[i]->slide == slide)
  1218.       tot++;
  1219.   sprintf(diagString, "In PrepareMult, number of popups is %d.\n",
  1220.       tot);
  1221.   PrintDTDiagnostics(diagString);
  1222.   tot = 0;
  1223.   for (i=0; i<numSlidesImages; i++)
  1224.     if (dtImage[i]->slide == slide)
  1225.       {
  1226.     tempImage = dtImage[i];
  1227.     globalPopup[tot] = PopupCreate(baseWindow->baseWindow,
  1228.                        tempImage->largeWidth,
  1229.                        tempImage->largeHeight);
  1230.         globalCanvas[tot] = CanvasCreate(globalPopup[tot],
  1231.                      tempImage->largeWidth,
  1232.                      tempImage->largeHeight);
  1233.     xv_set(globalCanvas[tot], XV_KEY_DATA, canvasKeyData, i, NULL);    /* Tell this canvas which image it's supposed to draw */
  1234.     XSetFunction(display, theGC, GXcopy); 
  1235.     
  1236.     if (tempImage->largeImage == (XImage*)NULL)            /* If the largeImage doesn't exist, create it first. */
  1237.     tempImage->largeImage = Resize(tempImage->imageData,
  1238.                       tempImage->origWidth,
  1239.                       tempImage->origHeight,
  1240.                       tempImage->largeWidth,
  1241.                       tempImage->largeHeight);
  1242.     tot++;
  1243.       }
  1244.   popupTot = tot;
  1245. }                                    /* end function PrepareMultipleWindowsForDisplay */
  1246.  
  1247.  
  1248. void PlaceImage(Window win, int imageNum)
  1249. {
  1250.   IMAGE    tempImage;
  1251.   
  1252.   PrintDTDiagnostics("Entering PlaceImage.\n");
  1253.   tempImage = dtImage[imageNum];
  1254.   XPutImage(display, win, theGC, tempImage->largeImage, 0, 0, 0, 0,
  1255.         tempImage->largeWidth, tempImage->largeHeight);
  1256. }                                    /* end function PlaceImage */
  1257.  
  1258.  
  1259.  
  1260. /*
  1261.  * Repaint callback function for `popups'.
  1262.  */
  1263. void
  1264.   PopupRepaint(Canvas        canvas,
  1265.            Xv_window    paint_window,
  1266.            Display*        display,
  1267.            Window        xid,
  1268.            Xv_xrectlist*    rects)
  1269. {
  1270.   int        i, tot;
  1271.   int        imageNum = 0;
  1272.   Canvas    whichCanvas = (Canvas)NULL;
  1273.   int        whichImage = -1;
  1274.   
  1275.   PrintDTDiagnostics("Entering PopupRepaint.\n");
  1276.   for (i=0; i < popupTot; i++)                        /* Look for the canvas to be redrawn in the list of all... */
  1277.   {                                    /* ...canvases currently being shown */
  1278.     if (globalCanvas[i] == canvas)                    /* Was the correct canvas found? */
  1279.     {
  1280.       whichCanvas = canvas;                        /* Yes, set a variable saying so */
  1281.       imageNum = i;
  1282.     }
  1283.   }
  1284.   sprintf(diagString, "whichCanvas is %d.\n", whichCanvas);
  1285.   PrintDTDiagnostics(diagString);
  1286.   if (whichCanvas == (Canvas)NULL)                    /* No, the correct canvas was not found, exit immediately */
  1287.     return;
  1288.   XSetFunction(display, theGC, GXcopy);                    /* Continue preparing to re-draw this canvas */
  1289.   tot = 0;
  1290.   whichImage = xv_get(whichCanvas, XV_KEY_DATA, canvasKeyData);
  1291.   sprintf(diagString, "whichImage is %d.\n", whichImage);
  1292.   PrintDTDiagnostics(diagString);
  1293.   if (whichImage == -1)                            /* No, the correct image was not found, exit immediately */
  1294.     return;
  1295.   PlaceImage(xid, whichImage);                        /* Redraw the correct image on the correct canvas */
  1296. }                                    /* end function PopupRepaint */
  1297.  
  1298.  
  1299.  
  1300. /*
  1301.  * Create object `Popup' in the specified instance.
  1302.  */
  1303. Frame
  1304.   PopupCreate(Frame owner, int width, int height)
  1305. {
  1306.   Frame frame = (Frame)NULL;
  1307.   
  1308.   PrintDTDiagnostics("Entering PopupCreate...\t");
  1309.   frame = xv_create(owner, FRAME_CMD,
  1310.             XV_KEY_DATA, INSTANCE, xv_get(owner, XV_KEY_DATA, INSTANCE),
  1311.             XV_WIDTH, width,
  1312.             XV_HEIGHT, height,
  1313.             XV_LABEL, "",
  1314.             XV_SHOW, FALSE,
  1315.             FRAME_SHOW_FOOTER, FALSE,
  1316.             FRAME_SHOW_HEADER, FALSE,
  1317.             FRAME_SHOW_RESIZE_CORNER, TRUE,
  1318.             FRAME_CMD_PUSHPIN_IN, FALSE,
  1319.             NULL);
  1320.   sprintf(diagString, "Popup id is %d.\n", frame);
  1321.   PrintDTDiagnostics(diagString);
  1322. /*  xv_set(xv_get(frame, FRAME_CMD_PANEL), WIN_SHOW, FALSE, NULL);*/
  1323.   return frame;
  1324. }
  1325.  
  1326.  
  1327. /*
  1328.  * Create object `canvas' in the specified instance.
  1329.  */
  1330. Canvas
  1331.   CanvasCreate(Frame owner, int width, int height)
  1332. {
  1333.   Canvas canvas;
  1334.   
  1335.   PrintDTDiagnostics("Entering CanvasCreate...\t");
  1336.   canvas = xv_create(owner, CANVAS,
  1337.              XV_X, 0,
  1338.              XV_Y, 0,
  1339.              XV_WIDTH, width,
  1340.              XV_HEIGHT, height,
  1341.              CANVAS_REPAINT_PROC, PopupRepaint,
  1342.              CANVAS_X_PAINT_WINDOW, TRUE,
  1343.              NULL);
  1344.   sprintf(diagString, "Canvas id is %d.\n", canvas);
  1345.   PrintDTDiagnostics(diagString);
  1346.   xv_set(canvas_paint_window(canvas),     /* canvas_paint_window(canvas),  */
  1347.      WIN_CONSUME_EVENTS,
  1348.      WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS,
  1349.      NULL,
  1350.      WIN_EVENT_PROC, CanvasEventProc,
  1351.          NULL);
  1352.   return(canvas);
  1353. }                                    /* end function CanvasCreate */
  1354.  
  1355.  
  1356.  
  1357. /*
  1358.  * Called when an event is received in the gallery canvas.
  1359.  */
  1360. void
  1361.   CanvasEventProc(Xv_Window pw, Event *event, Notify_arg arg)
  1362. {
  1363.   if (event_is_ascii(event))
  1364.     {
  1365.       switch (event_id(event))
  1366.     {
  1367.     case 'q' : case 'Q' :
  1368.       window_done(pw);
  1369.       break;
  1370.       default : ;
  1371.     }
  1372.       return;
  1373.     }
  1374.   switch (event_action(event)) 
  1375.     {
  1376.     case ACTION_ADJUST :
  1377.     case MS_MIDDLE :
  1378.       window_done(pw);
  1379.       break;
  1380.       default : ;
  1381.     }
  1382. }
  1383.  
  1384.  
  1385. void KillPopups()
  1386. {
  1387.   int i;
  1388.   for (i=0; i<popupTot; i++)
  1389.   {
  1390.     xv_destroy_safe(globalPopup[i]);
  1391.     globalPopup[i] = (Frame)NULL;
  1392. /*    HidePopup(&(globalPopup[i]));*/
  1393.   }
  1394.   popupTot = 0;
  1395.   timeCount = 0;
  1396.   KillOldPopupsOnly();
  1397. }
  1398.  
  1399. void KillOldPopupsOnly()
  1400. {
  1401.   int i;
  1402.   
  1403.   sprintf(diagString, "In KillOldPopupsOnly, trying to erase %d popups.\n",
  1404.       oldPopupTot);
  1405.   PrintDTDiagnostics(diagString);
  1406.   for (i=0; i < oldPopupTot; i++)
  1407.   {
  1408. /*
  1409.     sprintf(diagString,
  1410.         "Commented the actual destroying of popup %d.\n",
  1411.         oldPopups[i]);
  1412.     PrintDTDiagnostics(diagString);
  1413. */
  1414.     HidePopup(&(oldPopups[i]));
  1415.     xv_destroy_safe(oldPopups[i]);
  1416.     oldPopups[i] = (Frame)NULL;
  1417.   }
  1418.   oldPopupTot = 0;
  1419. }
  1420.  
  1421.  
  1422. void EraseOldImage(int selectedSlideImage)
  1423. {
  1424.   PaintSlide(selectedSlideImage);
  1425. }                                    /* end function EraseOldImage */
  1426.  
  1427.  
  1428. void DrawNewImage(int selectedSlideImage)
  1429. {
  1430.   PaintSlide(selectedSlideImage);
  1431.   changes = True;
  1432.   UpdateHeader(True);
  1433. }
  1434.  
  1435.  
  1436. void NoImageSelected()
  1437. {
  1438.   notice_prompt(baseWindow->baseWindow, NULL,
  1439.         NOTICE_MESSAGE_STRINGS,
  1440.         "No image is selected.",
  1441.         "You must first select an image from the scrollong list.",
  1442.         NULL,
  1443.         NOTICE_BUTTON_YES, "OK",
  1444.         NULL);
  1445. }
  1446.   
  1447.  
  1448. void ClearList(Panel_item list)
  1449. {
  1450.   xv_set(list, PANEL_LIST_DELETE_ROWS, 0,
  1451.      (int)xv_get(list, PANEL_LIST_NROWS), NULL);
  1452. }
  1453.  
  1454.  
  1455. int NotifyChoice(Xv_opaque owner, char *string)
  1456. {
  1457.   int response = notice_prompt(owner, NULL,
  1458.                    NOTICE_MESSAGE_STRINGS,
  1459.                    string,
  1460.                    NULL,
  1461.                    NOTICE_BUTTON_YES, "Cancel",
  1462.                    NOTICE_BUTTON_NO, "Confirm",
  1463.                    NULL);
  1464.   if (response == NOTICE_YES)
  1465.     return Cancel;
  1466.   else
  1467.     return Confirm;
  1468. }
  1469.  
  1470.  
  1471. void FreeMemoryForSlide(int slideNum)
  1472. {
  1473.   int    imageID;
  1474.   SCR    theSlide;
  1475.   IMAGE    thisImage;
  1476.   
  1477.   theSlide = slide[slideNum];                        /* Point to the slide referenced by argument passed in */
  1478.   for (imageID = 0; imageID < theSlide->numberOfImages; imageID++)  /* Look at each image for this slide */
  1479.   {
  1480.     thisImage = dtImage[theSlide->imageIds[imageID]];            /* Point to one of this slide's image structures */
  1481.     if (thisImage == NULL)                        /* Don't bother trying to release memory that isn't there */
  1482.       return;
  1483.     if (thisImage->largeImage != (XImage*)NULL)
  1484.     XDestroyImage(thisImage->largeImage);
  1485.     thisImage->largeImage = NULL;
  1486.   }
  1487.   return;
  1488. }                                    /* end function FreeMemoryForSlide */
  1489.  
  1490.  
  1491. char*    MyMalloc(unsigned int size)
  1492. {
  1493.   sprintf(diagString, "+++++++++++++++In MyMalloc, about to allocate %d bytes.\n", size);
  1494.   PrintDTDiagnostics(diagString);
  1495.   return((char*)malloc(size));
  1496. }                                    /* end function MyMalloc */
  1497.  
  1498.  
  1499. void    PrintDTDiagnostics(char* theString)
  1500. {
  1501.   if (printDiags != 0)
  1502.     printf("%s", theString);
  1503.   return;
  1504. }                                    /* end function PrintDTDiagnostics */
  1505.  
  1506.  
  1507. /*
  1508.  * This function will update the header of the DisplayTool frame to
  1509.  * either the current document name, or untitled.
  1510.  * It will also specify the status of the file, if it has been modified.
  1511.  */
  1512. void UpdateHeader(modified)
  1513.      int modified;
  1514. {
  1515.   char label[100];
  1516.   
  1517.   if (modified == True)
  1518.   {
  1519.     sprintf(label, "DisplayTool Document :  \"%s\" (modified)", currentFilename);
  1520.   }
  1521.   else 
  1522.   {
  1523.     sprintf(label, "DisplayTool Document :  \"%s\" ", currentFilename);
  1524.   }
  1525.   xv_set(baseWindow->baseWindow,                    /* Update the main window's header */
  1526.      XV_LABEL, label,
  1527.      NULL);
  1528. }                                    /* end function UpdateHeader */
  1529.